/*
 * @lc app=leetcode.cn id=2166 lang=cpp
 *
 * [2166] 设计位集
 */

// @lc code=start
class Bitset
{
    typedef pair<int, int> PII;
    int size, base, ones, *data, n;

    PII _getBits(int idx)
    {
        int x = idx / base, y = idx % base;
        return {x, y};
    }

public:
    Bitset(int size) : size(size), base(30), ones(0)
    {
        // 向上取整
        n = size / base + (size % base != 0);
        data = new int[n];
        memset(data, 0, sizeof(int) * n);
    }

    void fix(int idx)
    {
        auto [x, y] = _getBits(idx);
        if ((data[x] & (1 << y)) == 0)
        {
            ones += 1;
            data[x] |= (1 << y);
        }
    }

    void unfix(int idx)
    {
        auto [x, y] = _getBits(idx);
        if ((data[x] & (1 << y)))
        {
            ones -= 1;
            data[x] ^= (1 << y);
        }
    }

    void flip()
    {
        for (int i = 0; i < n; i++)
        {
            data[i] = ~data[i];
        }
        ones = size - ones;
    }

    bool all()
    {
        return ones == size;
    }

    bool one()
    {
        return ones != 0;
    }

    int count()
    {
        return ones;
    }

    string toString()
    {
        int m = size / base, rest = size % base;
        string res = "";
        for (int i = 0; i < m; i++)
        {
            for (int j = 0; j < base; j++)
            {
                if ((data[i] & (1 << j)))
                {
                    res += "1";
                }
                else
                {
                    res += "0";
                }
            }
        }
        for (int j = 0; j < rest; j++)
        {
            if ((data[m] & (1 << j)))
            {
                res += "1";
            }
            else
            {
                res += "0";
            }
        }

        return res;
    }
};

/**
 * Your Bitset object will be instantiated and called as such:
 * Bitset* obj = new Bitset(size);
 * obj->fix(idx);
 * obj->unfix(idx);
 * obj->flip();
 * bool param_4 = obj->all();
 * bool param_5 = obj->one();
 * int param_6 = obj->count();
 * string param_7 = obj->toString();
 */
// @lc code=end
